<?php
/**
 * @deprecated (暂时不用了！)
 * 商品属性的管理
 * Author: lyun
 * Date: 2018/3/29
 * Created by Panxsoft.
 */


namespace App\Http\Controllers\Admin\Panx\Product;

use App\Http\Controllers\ApiController;
use App\Http\Requests\Admin\Panx\Product\ProductAttributeStoreRequest;
use App\Http\Requests\Admin\Panx\Product\ProductAttributeUpdateRequest;
use App\Models\Panx\Attribute;
use App\Models\Panx\AttributeValue;
use App\Models\Panx\Category;
use App\Models\Panx\ProductMod;
use App\Models\Panx\ProductPivotAttributeValue;
use App\Services\Utils\Transaction;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;

class ProductAttributeController extends ApiController
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        /** @var LengthAwarePaginator $attributes */
        $attributes = Attribute::with('productMod','attributeValues')
            ->latest()
            ->paginate();

        $attributes->transform(function(Attribute $attribute){
            $attribute->values = $attribute->attributeValues->pluck('value');

            return $attribute;
        });

        return $this->response(compact('attributes'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $product_models = ProductMod::all();

        return $this->response(compact('product_models'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  ProductAttributeStoreRequest $request
     * @return \Illuminate\Http\Response
     * @throws \Exception
     */
    public function store(ProductAttributeStoreRequest $request)
    {
//        $attribute_data = $this->assembleAttribute($request);
//
//        $stored = Transaction::handle(function() use($request, $attribute_data) {
//            $attribute = Attribute::create($attribute_data);
//
//            $this->storeAttributeValue($request, $attribute);
//
//            return true;
//        });
//
//        return $this->response(compact('stored'));
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  ProductAttributeUpdateRequest $request
     * @param  int $id
     * @return \Illuminate\Http\Response
     * @throws \Exception
     */
    public function update(ProductAttributeUpdateRequest $request, $id)
    {
//        /** @var Attribute $attribute */
//        $attribute = Attribute::find($id);
//            $this->checkItemExist($attribute, '商品属性名称');
//
//        $attribute_data = $this->assembleAttribute($request);
//
//        $updated = Transaction::handle(function() use($request, $attribute, $attribute_data) {
//            $attribute->update($attribute_data);
//
//            $this->updateAttributeValue($request, $attribute);
//
//            return true;
//        });
//
//        return $this->response(compact('updated'));
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int $id
     * @return void
     */
    public function destroy($id)
    {
        // 已经关联了商品，不能删除！
    }

    /**
     * @param ProductAttributeStoreRequest|ProductAttributeUpdateRequest|Request $request
     * @return array
     */
    private function assembleAttribute(Request $request)
    {
        return [
            'product_mod_id' => $request->product_mod_id,
            'name'             => $request->name,
        ];
    }

    /**
     * @param ProductAttributeStoreRequest $request
     * @param Attribute $attribute
     */
    private function storeAttributeValue(ProductAttributeStoreRequest $request, Attribute $attribute)
    {
        $values = $request->values;

        foreach($values as $value)
        {
            $spec_value = [
                'attribute_id' => $attribute->id,
                'value'        => $value,
            ];

            AttributeValue::create($spec_value);
        }
    }

    /**
     * @param ProductAttributeUpdateRequest $request
     * @param Attribute $attribute
     * @return bool
     */
    private function updateAttributeValue(ProductAttributeUpdateRequest $request,
                                          Attribute $attribute)
    {
        list(
            $new_attr_values,
            $update_attr_values,
            $delete_attr_val_ids
        ) = $this->normalizeUpdateAttributeValueData($request, $attribute);
        
        $this->updateCreateAttributeValues($new_attr_values);

        $this->updateExistAttributeValues($update_attr_values);

        $this->updateDeleteAttributeValues($delete_attr_val_ids);

        return true;
    }
    
    /**
     * @param ProductAttributeUpdateRequest $request
     * @param Attribute $attribute
     * @return array
     */
    private function normalizeUpdateAttributeValueData(ProductAttributeUpdateRequest $request,
                                                       Attribute $attribute)
    {
        $new_attr_values = [];
        $need_update_attr_vals = [];
        $exist_attr_values = $attribute->attributeValues;
    
        foreach ($request->attribute_values as $req_attr_val) {
            $req_attr_val_id = $req_attr_val['id'];
            
            if (! $req_attr_val_id) {
                $req_attr_val['attribute_id'] = $attribute->id;
                array_push($new_attr_values, $req_attr_val);
            } else {
                /** @var AttributeValue $exist_attr_value */
                $exist_attr_value = $exist_attr_values->find($req_attr_val_id);
                
                if ($exist_attr_value && $exist_attr_value->value !== $req_attr_val['value']) {
                    array_push($need_update_attr_vals, $req_attr_val);
                }
            }
        }
        
        $req_attr_val_ids = array_column($request->attribute_values, 'id');
        $delete_attr_val_ids = $exist_attr_values->whereNotIn('id', $req_attr_val_ids)
            ->pluck('id')->all();
    
        return [
            $new_attr_values,
            $need_update_attr_vals,
            $delete_attr_val_ids
        ];
    }
    
    /**
     * @param array $new_attr_values
     */
    private function updateCreateAttributeValues(array $new_attr_values)
    {
        AttributeValue::insert($new_attr_values);
    }
    
    /**
     * @param array $update_attr_values
     */
    private function updateExistAttributeValues(array $update_attr_values)
    {
        foreach ($update_attr_values as $attr_val) {
            AttributeValue::where('id', $attr_val['id'])->update([
                'value' => $attr_val['value'],
            ]);
        }
    }
    
    /**
     * @param array $delete_ids
     */
    private function updateDeleteAttributeValues(array $delete_ids)
    {
        if (! count($delete_ids)) return;
        
        AttributeValue::destroy($delete_ids);
    
        ProductPivotAttributeValue::whereIn('attribute_value_id', $delete_ids)->delete();
    }
}
